package model

import (
	"context"
	"time"

	"gorm.io/gorm"
)

type UserKey string

const AuthUserKey UserKey = "auth_user"

type BaseModal struct {
	ID        int64     `gorm:"type:bigint;primary_key" json:"id"`
	CreateBy  int64     `gorm:"type:bigint;column:create_by" json:"create_by"`
	CreatedAt time.Time `gorm:"type:datetime;column:create_at" json:"created_at"`
	UpdatedBy int64     `gorm:"type:bigint;column:update_by" json:"update_by"`
	UpdatedAt time.Time `gorm:"type:datetime;column:update_at" json:"updated_at"`
	DeletedBy int64     `gorm:"type:bigint;column:delete_by" json:"delete_by"`
	DeletedAt int64     `gorm:"type:bigint;column:delete_at" json:"deleted_at"`
	Flag      bool      `gorm:"type:tinyint;column:flag" json:"flag"`
}

// TableName 返回表名 - 应由子模型重写
func (b *BaseModal) TableName() string {
	return "base_model"
}

// BeforeUpdate 钩子函数：设置更新人和更新时间
func (b *BaseModal) BeforeUpdate(tx *gorm.DB) error {
	if user, ok := extractUserFromContext(tx.Statement.Context); ok {
		b.UpdatedBy = user.ID
	}
	b.UpdatedAt = time.Now()
	return nil
}

// BeforeCreate 钩子函数：设置创建人、更新人和时间戳
func (b *BaseModal) BeforeCreate(tx *gorm.DB) error {
	if user, ok := extractUserFromContext(tx.Statement.Context); ok {
		b.CreateBy = user.ID
		b.UpdatedBy = user.ID
	}
	now := time.Now()
	b.CreatedAt = now
	b.UpdatedAt = now

	// 如果未设置标志，则设置默认值
	if !b.Flag {
		b.Flag = true
	}

	return nil
}

// extractUserFromContext 安全地从上下文中提取用户信息
func extractUserFromContext(ctx context.Context) (*User, bool) {
	if ctx == nil {
		return nil, false
	}

	// 尝试获取指针类型的用户
	if user, ok := ctx.Value(AuthUserKey).(*User); ok && user != nil {
		return user, true
	}

	// 备选：尝试获取值类型的用户
	if user, ok := ctx.Value(AuthUserKey).(User); ok {
		return &user, true
	}

	return nil, false
}
